package homework.exp06;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

public class J {
    static Scanner cin = null;

    static {
        try {
            cin = new Scanner(new FileInputStream(new File("src/homework/exp06/J.in")));
        } catch (IOException e) {
            cin = new Scanner(System.in);
        }
    }


    public static void main(String[] args) {

        int n = cin.nextInt(); // 读取顶点数量
        int[][] graph = new int[n][n]; // 邻接矩阵表示图
        int[] inDegree = new int[n]; // 存储每个顶点的入度
        List<Integer> result = new ArrayList<>(); // 存储拓扑排序结果
        Queue<Integer> queue = new LinkedList<>(); // 使用队列来处理入度为零的顶点

        // 读取邻接矩阵并计算每个顶点的入度
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                graph[i][j] = cin.nextInt();
                if (graph[i][j] == 1) {
                    inDegree[j]++;
                }
            }
        }

        // 找到所有入度为零的顶点
        for (int i = 0; i < n; i++) {
            if (inDegree[i] == 0) {
                queue.add(i);
            }
        }

        // 处理顶点
        while (!queue.isEmpty()) {
            int current = queue.poll(); // 从队列中取出一个顶点
            result.add(current); // 将其加入结果列表
            for (int i = 0; i < n; i++) {
                if (graph[current][i] == 1) {
                    inDegree[i]--; // 减少相邻顶点的入度
                    if (inDegree[i] == 0) {
                        queue.add(i); // 如果入度变为零，则将其加入队列
                    }
                }
            }
        }

        // 检查是否存在环
        if (result.size() != n) {
            System.out.println("ERROR"); // 如果结果列表中的顶点数量不等于图中的顶点总数，说明存在环
        } else {
            for (int i = 0; i < result.size(); i++) {
                System.out.print(result.get(i) + " "); // 输出拓扑排序结果
            }
            System.out.println();
        }
    }
}